package com.ihr360.excel.view;

import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.view.document.AbstractXlsView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;

public class ExcelView extends AbstractXlsView {
    public static final String MODEL_KEY = "excel";
    public static final String UTF_16LE = "UTF-16LE";
    public static final String UTF_8 = "UTF-8";

    @Override
    protected void buildExcelDocument(Map<String, Object> model,
                                      Workbook workbook,
                                      HttpServletRequest request,
                                      HttpServletResponse response) throws Exception {
        ExcelSheetDef sheetDef = (ExcelSheetDef) model.get(MODEL_KEY);
        response.setContentType("application/octet-stream");
        String csvFileName = sheetDef.getTitle() != null ? sheetDef.getTitle() : "export-excel";
        String headerKey = "Content-Disposition";
        String headerValue = null;
        String encoder = UTF_8;
        try {
            headerValue = String.format("attachment; filename=%s.xls",
                    URLEncoder.encode(csvFileName, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            headerValue = String.format("attachment; filename=%s.xls",
                    csvFileName);
            logger.info(e.getMessage(), e);
        }
        response.setCharacterEncoding(encoder);
        response.setHeader(headerKey, headerValue);
        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        if (sheetDef == null) {
            return;
        }

        List<IExcelRowDef<String>> rows = sheetDef.getRows();
        List<ExcelColumnDef> columns = sheetDef.getColumnDefs();

        // create excel xls sheet
        Sheet sheet = workbook.createSheet(csvFileName);
        sheet.setDefaultColumnWidth(30);

        // create style for header cells
        CellStyle style = workbook.createCellStyle();
        Font font = workbook.createFont();
        font.setFontName("Arial");
        style.setFillForegroundColor(HSSFColor.BLUE.index);
        font.setBold(true);
        font.setColor(HSSFColor.BLACK.index);
        style.setFont(font);
        int rowIndex = 0;
        Row header = sheet.createRow(rowIndex++);

        if (!CollectionUtils.isEmpty(columns)) {
            int colIndex = 0;
            for (ExcelColumnDef columnDef : columns) {
                header.createCell(colIndex).setCellValue(columnDef.getName());
                header.getCell(colIndex).setCellStyle(style);
                colIndex++;
            }
        }
        if (sheetDef.isShowColumnCode()) {
            Row subHeader = sheet.createRow(rowIndex++);
            if (!CollectionUtils.isEmpty(columns)) {
                int colIndex = 0;
                for (ExcelColumnDef columnDef : columns) {
                    subHeader.createCell(colIndex).setCellValue(columnDef.getCode());
                    subHeader.getCell(colIndex).setCellStyle(style);
                    colIndex++;
                }
            }
        }

        if (CollectionUtils.isEmpty(rows)) {
            return;
        }

        for (IExcelRowDef<String> row : rows) {
            Row userRow = sheet.createRow(rowIndex++);
            int colIndex = 0;
            Map<String, String> rowData = row.getRowData();
            for (ExcelColumnDef columnDef : columns) {
                Object value = rowData.get(columnDef.getCode());
                if (value != null) {
                    userRow.createCell(colIndex).setCellValue(value.toString());
                } else {
                    userRow.createCell(colIndex).setCellValue("");
                }
                colIndex++;
            }
        }
    }
}